package c2.group.business;

import c2.advanced.business.AdvancedBody;
import c2.advanced.business.base.AdvancedModule;
import c2.advanced.business.base.ModuleRequirements;
import c2.advanced.server.configuration.SetupContext;
import c2.advanced.share.DbFacade;
import c2.advanced.share.RpcSuit;
import c2.group.business.demo.DemoModule;
import c2.group.business.gradepvp.GradePvpModule;
import c2.group.business.tb.TBModule;
import c2.group.business.teampvp.TeamPvpModule;
import c2.group.server.GroupServerApplication;
import c2.group.share.DbFacade4Group;
import c2.group.share.RpcSuit4Group;
import cp.solution.pattern.exception.ThrowingConsumer;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

@Slf4j
public class GroupBody extends AdvancedBody {

    @NotNull
    @Contract(pure = true)
    public static String version() {
        return "2023-10-10 17:42";
    }

    @Override
    protected RpcSuit createRpc() {
        return new RpcSuit4Group();
    }

    // 以下是共享服务区域
    public DbFacade4Group db = new DbFacade4Group();
    @Override
    public DbFacade dbBase() {
        return db;
    }

    // 以下是业务逻辑区域
    public DemoModule demo = new DemoModule(this);
    public GradePvpModule gradePvp = new GradePvpModule(this);

    public TBModule tb = new TBModule(this);
    public TeamPvpModule teamPvp = new TeamPvpModule(this);

    @Getter
    private AdvancedModule[] modules = new AdvancedModule[] { common, demo,teamPvp,gradePvp,tb};

    public void setup(SetupContext context) throws Exception {
        time.setup();
        api.setup(context);
        db.setup(context);
        table.setup(context);
        play.setup();
        fightHandler.setUp(play.getPlayBuildContext());

        rpc.setup(context);
    }

    public void initModules(ModuleRequirements requirements) {
        modulesDo(m -> m.initIndependent(requirements), "独立の初始化 initIndependent()");
        modulesDo(m -> m.initDependent(), "依赖の初始化 initDependent()");
    }

    private void modulesDo(ThrowingConsumer<AdvancedModule> consumer, String parse) {
        for(AdvancedModule module : modules) {
            log.info("模块[{}] {} 开始", module.getName(), parse);
            long beginTime = System.currentTimeMillis();
            try {
                consumer.accept0(module);
            } catch (Throwable e) {
                moduleFail(module, e, "initIndependent");
            }
            log.info("模块[{}] {} 完成 耗时{}ms", module.getName(), parse, (System.currentTimeMillis()-beginTime));
        }
    }

    private static void moduleFail(AdvancedModule module, Throwable e, String phase) {
        String errMsg = "模块["+module.getName()+"] "+phase+" 异常, 因为：" + e.getMessage();
        log.error(errMsg, e);
        GroupServerApplication.shutdown(errMsg);
    }

    public void shutdownModules() {
        modulesDo(m -> m.onShutdown(), "模块关闭 onShutdown()");
    }
}
